package de.jtserver;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.ScriptableObject;

import de.jtserver.model.JTalkScript;

public class JtalkBackend extends HttpServlet {
	private static final long serialVersionUID = -596187955763327842L;
	Logger logger = Logger.getLogger("de.jtserver");

	HashMap<String, ScriptableObject> scopes = new HashMap<String, ScriptableObject>();

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		logger.fine("doPost im Backend!");

		String commandString = (String) req.getParameter("commandString");
		String owner = (String) req.getParameter("owner");
		String[] contentStringArray = req.getParameter("contentString").split("!");
		String contentString = contentStringArray[0];
		String parameters = null;
		if (contentStringArray.length > 1) {
			parameters = contentStringArray[1];
		}

		Context ctx = initContext();

		if (commandString.equalsIgnoreCase("server")) {
			ScriptableObject scope = null;

			if (scopes.containsKey(owner)) {
				scope = scopes.get(owner);
			} else {
				scope = initScope(owner, ctx);
			}

			NativeJavaObject nativeJavaObject = (NativeJavaObject) ScriptableObject.getProperty(scope, "javaobjects");
			HashMap javaObjects = (HashMap) nativeJavaObject.unwrap();

			Iterator it = javaObjects.keySet().iterator();
			while (it.hasNext()) {
				Object key = it.next();
				System.out.println(key + " : " + javaObjects.get(key));
			}

			StringBuffer resultString = new StringBuffer();
			ScriptableObject.putProperty(scope, "resultString", resultString);

			logger.warning("evaluating ...");
			if (parameters != null) {
				ctx.evaluateString(scope, "smalltalk." + contentString + "._new()._runRemote_('" + parameters + "');",
						"<cmd>", 1, null);
			} else {
				ctx.evaluateString(scope, "smalltalk." + contentString + "._new()._runRemote();", "<cmd>", 1, null);
			}

			System.out.println("resultString: " + resultString);

			// Context.exit();

			resp.setContentType("application/x-javascript");
			resp.getWriter().println(resultString);

		} else if (commandString.equalsIgnoreCase("reset")) {
			if (scopes.containsKey(owner)) {
				scopes.remove(owner);
				initScope(owner, ctx);
			}
		}
	}

	private ScriptableObject initScope(String owner, Context ctx) throws FileNotFoundException, IOException {
		ScriptableObject scope;
		JTalkScript jTalkScript = JScriptHelper.getJTalkScript(owner);
		// no previously serialized smalltalk-object in the database
		String script = jTalkScript.getScript();
		scope = JScriptHelper.initJScript(ctx, script);
		scopes.put(owner, scope);
		return scope;
	}

	private Context initContext() {
		Context ctx = Context.enter();
		ctx.setOptimizationLevel(-1);
		return ctx;
	}

}
